﻿#region

using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using MediaSage.Lib.Database;
using NHibernate;
using NHibernate.Context;
using NHibernate.Tool.hbm2ddl;

#endregion

namespace MediaSage.Lib.Utilities
{
    /// <summary>
    ///     Static class for dealing with the NHibernate database objects
    /// </summary>
    public static class DBUtil
    {
        #region Fields

        private static ISession session;
        private static ISessionFactory sessionFactory;

        #endregion Fields

        #region Methods

        public static ISessionFactory GetSessionFactory()
        {
            return sessionFactory;
        }

        public static void CreateTables(string databaseLocation)
        {
            if (sessionFactory != null && !sessionFactory.IsClosed)
            {
                sessionFactory.Close();
            }

#if DEBUG
            sessionFactory = Fluently.Configure()
                .Database(MsSqlCeConfiguration.Standard.ConnectionString(c =>
                                                                         c.Is("data source=" + databaseLocation))
                )
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<DatabaseBaseEntity>())
                .ExposeConfiguration(x =>
                                         {
                                             x.SetProperty("current_session_context_class", "thread_static");
                                             x.SetProperty("adonet.batch_size", "15");
                                         })
                .Diagnostics(dia =>
                                 {
                                     dia.Enable();
                                     dia.OutputToFile(".\\fluent.log");
                                 }).
                BuildConfiguration().BuildSessionFactory();
#else
            sessionFactory = Fluently.Configure()
                .Database(MsSqlCeConfiguration.Standard.ConnectionString(c =>
                                                                         c.Is("data source=" + databaseLocation))
                )
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<DatabaseBaseEntity>())
                .ExposeConfiguration(x => { x.SetProperty("current_session_context_class", "thread_static"); x.SetProperty("adonet.batch_size", "15"); }).
                BuildConfiguration().BuildSessionFactory();
#endif
            new SchemaExport(GetConfig(databaseLocation)).Execute(true, true, false);
        }

        public static ISession GetSession()
        {
            if (sessionFactory == null)
            {
                return null;
            }
            if (session != null)
            {
                if (!session.IsOpen)
                {
                    session = sessionFactory.OpenSession();
                }
                return session;
            }
            else
            {
                if (session == null)
                {
                    session = sessionFactory.OpenSession();
                    CurrentSessionContext.Bind(session);
                    return session;
                }
            }
            if (CurrentSessionContext.HasBind(sessionFactory))
            {
                session = sessionFactory.GetCurrentSession();
            }

            return session;
        }

        public static void Init(string databaseLocation)
        {
            if (sessionFactory == null)
            {
                sessionFactory = Fluently.Configure()
                    .Database(MsSqlCeConfiguration.Standard.ConnectionString(c =>
                                                                             c.Is("data source=" + databaseLocation))
                    )
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<DatabaseBaseEntity>()).ExposeConfiguration(
                        x => { x.SetProperty("current_session_context_class", "thread_static"); }).BuildSessionFactory();
            }
        }

        private static NHibernate.Cfg.Configuration GetConfig(string databaseLocation)
        {
            return GetMappings().Database(MsSqlCeConfiguration.Standard.ConnectionString(c =>
                                                                                         c.Is("data source=" +
                                                                                              databaseLocation))
                )
                .BuildConfiguration();
        }

        private static FluentConfiguration GetMappings()
        {
            return Fluently.Configure().Mappings(m => m.FluentMappings.AddFromAssemblyOf<DatabaseBaseEntity>());
        }

        #endregion Methods
    }
}